package com.umfwechat.util.email;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.apache.log4j.Logger;

import com.umfwechat.util.PropertyUtil;
import com.umpay.operation.util.CommonUtils;

public class SendMailUtil {

    private static Logger log = Logger.getLogger(SendMailUtil.class);

    /**
     * 简单的邮件发送
     * @param mailto
     * @param subject
     * @param mailContent
     */
    public static void sendMail(String mailto,String subject,String mailContent){
        sendMail(mailto,"", subject, mailContent, null);
    }

    /**
     * 邮件发送(带附件)
     * @param mailto
     * @param subject
     * @param mailContent
     * @param fileList
     */
    public static void sendMail(String mailto,String subject,String mailContent,List<File> fileList){
        sendMail(mailto,"", subject, mailContent, fileList);
    }

    /**
     * 邮件发送(带附件)
     * @param mailto
     * @param mailcc
     * @param subject
     * @param mailContent
     * @param fileList
     */
    public static void sendMail(String mailto,String mailcc,String subject, String mailContent, List<File> fileList){
        log.info("发送邮件通知...");
        Properties properties = PropertyUtil.getProperties("umfWeChatPlat_appConf.properties");
        String smtpserver = properties.getProperty("mail.smtp.host"); //邮箱服务器设置
        String smtpport = properties.getProperty("mail.smtp.port"); //邮件服务器默认端口
        String smtpuser = properties.getProperty("mail.username"); //邮件服务器登陆用户名
        String smtppwd = properties.getProperty("mail.password"); //邮件服务器登陆密码
        String mailfrom = properties.getProperty("mail.from"); //发件人
        String timeout = properties.getProperty("mail.timeout"); //超时时间

        try {
            AbstractMailSender sender = new SMTPMailSender();
            sender.setServerHost(smtpserver);
            sender.setServerPort(Integer.parseInt(smtpport)); //端口
            sender.setAuthen(true);
            sender.setUserName(smtpuser);
            sender.setUserPwd(smtppwd);
            sender.setFrom(mailfrom); //发送人
            sender.setTo(mailto);   //发送到人员
            sender.setCc(mailcc);  //抄送人
            sender.setSubject(subject);
            sender.setTxtContent(mailContent); //邮件内容
            sender.setTimeout(timeout);//超时时间
            log.info(String.format("发送邮件smtpserver:%s,smtpport:%s,smtpuser:%s,smtppwd:%s,mailfrom:%s,mailto:%s,mailcc:%s",
                    smtpserver,smtpport,smtpuser,smtppwd,mailfrom,mailto,mailcc));
            if(fileList!= null&&fileList.size()>0){  //是否发送附件
                sender.setAttachFile(fileList);  //增加附件
            }
            sender.sendMail();   //发送邮件
            log.info("邮件发送成功！");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("发送邮件异常：" + e.getMessage(), e);
        }
    }



    // 以HTML格式发送邮件
    public static boolean sendHtmlMail(MailInfo mailInfo) {
        //判断是否需要身份认证
        Authenticator authenticator = null;
        Properties properties = mailInfo.getProperties();
        if (mailInfo.isValidate()) {
            // 如果需要身份认证，则创建一个密码验证器
            authenticator = new Authenticator(mailInfo.getUsername(), mailInfo.getPassword());
        }

        // 根据邮件会话属性和密码验证器构造一个发送邮件的session
//		Session sendMailSession = Session.getDefaultInstance(properties, authenticator);
        Session sendMailSession = Session.getInstance(properties, authenticator);

        try{
            Message mailMessage = new MimeMessage(sendMailSession);//根据session创建一个邮件消息
            Address from = new InternetAddress(mailInfo.getFromAddress());//创建邮件发送者地址
            mailMessage.setFrom(from);//设置邮件消息的发送者
            Address to = new InternetAddress(mailInfo.getToAddress());//创建邮件的接收者地址
            mailMessage.setRecipient(Message.RecipientType.TO, to);//设置邮件消息的接收者
            mailMessage.setSubject(mailInfo.getSubject());//设置邮件消息的主题
            mailMessage.setSentDate(new Date());//设置邮件消息发送的时间

            //MimeMultipart类是一个容器类，包含MimeBodyPart类型的对象
            Multipart mainPart = new MimeMultipart();
            MimeBodyPart messageBodyPart = new MimeBodyPart();//创建一个包含HTML内容的MimeBodyPart
            //设置HTML内容
            messageBodyPart.setContent(mailInfo.getContent(),"text/html; charset=utf-8");
            mainPart.addBodyPart(messageBodyPart);

            //存在附件
            List<File> filePaths = mailInfo.getAttachFileNames();
            if (filePaths != null && filePaths.size() > 0) {
                for(File file : filePaths){
                    messageBodyPart = new MimeBodyPart();
                    if(file.exists()){//附件存在磁盘中
                        FileDataSource fds = new FileDataSource(file);//得到数据源
                        messageBodyPart.setDataHandler(new DataHandler(fds));//得到附件本身并至入BodyPart
//						BASE64Encoder enc = new BASE64Encoder();
                        log.info("添加邮件附件---KKL ---:" + fds.getName() );
                        messageBodyPart.setFileName(MimeUtility.encodeText(fds.getName()));//得到文件名同样至入BodyPart
                        mainPart.addBodyPart(messageBodyPart);
                    }
                }
            }

            //将MimeMultipart对象设置为邮件内容
            mailMessage.setContent(mainPart);
            Transport.send(mailMessage);//发送邮件

            log.info("邮件发送成功！");

            return true;
        }catch (Exception e) {
            log.error("发送邮件异常：" + e.getMessage(), e);
            e.printStackTrace();
        }
        return false;
    }

    /**  
     * 以HTML格式发送邮件  
     * @param mailInfo 待发送的邮件信息  
     */   
   public static boolean sendHtmlMail(MailSenderInfo mailInfo){   
     // 判断是否需要身份认证   
	   Authenticator authenticator = null;  
     Properties pro = mailInfo.getProperties();  
     //如果需要身份认证，则创建一个密码验证器    
     if (mailInfo.isValidate()) {   
       authenticator = new Authenticator(mailInfo.getUserName(), mailInfo.getPassword());  
     }   
     // 根据邮件会话属性和密码验证器构造一个发送邮件的session   
     Session sendMailSession = Session.getInstance(pro,authenticator);   
     try {   
     // 根据session创建一个邮件消息   
     Message mailMessage = new MimeMessage(sendMailSession);   
     // 创建邮件发送者地址   
     Address from = new InternetAddress(mailInfo.getFromAddress(),mailInfo.getFromName());   
     // 设置邮件消息的发送者   
     mailMessage.setFrom(from);   
     // 创建邮件的接收者地址，并设置到邮件消息中   
     Address to = new InternetAddress(mailInfo.getToAddress());   
     // Message.RecipientType.TO属性表示接收者的类型为TO   
     mailMessage.setRecipient(Message.RecipientType.TO,to);   // 只发送给一个邮箱    
     // 设置邮件消息的主题   
     mailMessage.setSubject(mailInfo.getSubject());   
     // 设置邮件消息发送的时间   
     mailMessage.setSentDate(new Date());   
     // MiniMultipart类是一个容器类，包含MimeBodyPart类型的对象   
     Multipart mainPart = new MimeMultipart();   
     // 创建一个包含HTML内容的MimeBodyPart   
     BodyPart html = new MimeBodyPart();   
     // 设置HTML内容   
     html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");  
     mainPart.addBodyPart(html); 
     
     ///////////// 2014-12-25 附件 start //////////////
     String [] attachmentPaths = mailInfo.getAttachFilePaths();
     if(attachmentPaths!=null&&attachmentPaths.length>0){
   	    for(int i=0;i<attachmentPaths.length;i++){
   	    	MimeBodyPart mbp3 = null;
 		      if(CommonUtils.isNotEmpty(attachmentPaths)) {
 		    	  mbp3 = new MimeBodyPart();  
// 		    	  if(CommonUtils.isNotEmpty(attachmentPaths[i])) {
 		    		  log.info("要发送的【商户证书】附件文件：" + attachmentPaths[i]);
 		    		  FileDataSource fds2 = new FileDataSource(attachmentPaths[i]);  
 		    		  DataHandler dh2 = new DataHandler(fds2);  
 		    		  mbp3.setDataHandler(dh2);  
 		    		  try {
 		    			  mbp3.setFileName(MimeUtility.encodeText(fds2.getName()));
 		    		  } catch (UnsupportedEncodingException e) {
 		    			  e.printStackTrace();
 		    		  }  
 		    	 // }
 		      }
 		    if(null != mbp3)
 	    	  mainPart.addBodyPart(mbp3);
   	    }
     }
     ///////////// 2014-12-25 附件 end   //////////////
     
     // 将MiniMultipart对象设置为邮件内容   
     mailMessage.setContent(mainPart);   
     // 发送邮件   
     Transport.send(mailMessage);   
     return true;   
     } catch (MessagingException ex) {   
         log.error("邮件发送异常："+ex);
     } catch (UnsupportedEncodingException e) {
   	  log.error("邮件发送异常："+e);
	}   
     return false;   
   }   
    
    public static boolean sendPicHtmlMail(MailInfo mailInfo, String pngFileName){
        //判断是否需要身份认证
        Authenticator authenticator = null;
        Properties properties = mailInfo.getProperties();
        if (mailInfo.isValidate()) {
            // 如果需要身份认证，则创建一个密码验证器
            authenticator = new Authenticator(mailInfo.getUsername(), mailInfo.getPassword());
        }

        // 根据邮件会话属性和密码验证器构造一个发送邮件的session
        properties.setProperty("mail.smtp.connectiontimeout", mailInfo.getConnectTimeout());//设置连接超时
        properties.setProperty("mail.smtp.timeout", mailInfo.getTimeout());			//I/O读写超时设置
		Session sendMailSession = Session.getDefaultInstance(properties, authenticator);
//        Session sendMailSession = Session.getInstance(properties, authenticator);
        try{
            Message mailMessage = new MimeMessage(sendMailSession);//根据session创建一个邮件消息
            InternetAddress from = new InternetAddress(mailInfo.getFromAddress());//创建邮件发送者地址
            from.setPersonal(MimeUtility.encodeText(mailInfo.getFromAddressName()));
            mailMessage.setFrom(from);//设置邮件消息的发送者
            //创建邮件的接收者地址
            mailMessage.setRecipients(Message.RecipientType.TO, InternetAddress.parse(mailInfo.getToAddress()));//设置邮件消息的接收者
            mailMessage.setSubject(mailInfo.getSubject());//设置邮件消息的主题
            mailMessage.setSentDate(new Date());//设置邮件消息发送的时间

            //MimeMultipart类是一个容器类，包含MimeBodyPart类型的对象
            Multipart mainPart = new MimeMultipart();

            // 一个消息包，类型是混杂的
//			MimeMultipart msgMultipart = new MimeMultipart("mixed");// 指定为混合关系
            mailMessage.setContent(mainPart);
            // 这是消息包里面的一个消息体块
            MimeBodyPart content = new MimeBodyPart();
            mainPart.addBodyPart(content);
            // 消息体块包含了一组有依赖关系的元素
            MimeMultipart bodyMultipart = new MimeMultipart(); // 依赖关系
            // 这两个依赖关系的元素是HTML文本内容和依赖的图片资源
            MimeBodyPart htmlPart = new MimeBodyPart();
            MimeBodyPart gifPart = new MimeBodyPart();
            // TODO 组装的顺序非常重要，一定要先组装文本域
            DataSource gifds = new FileDataSource(new File(pngFileName));
            DataHandler gifdh = new DataHandler(gifds);
            gifPart.setDataHandler(gifdh);
            gifPart.setHeader("Content-ID", "<action>");
            gifPart.setContentID("<action>");

            //设置HTML内容
            htmlPart.setContent(mailInfo.getContent(),"text/html; charset=GBK");
            log.info("组装邮件");
            bodyMultipart.addBodyPart(htmlPart);
            bodyMultipart.addBodyPart(gifPart);
            bodyMultipart.setSubType("related");

            //存在附件
            List<File> filePaths = mailInfo.getAttachFileNames();
            if (filePaths != null && filePaths.size() > 0) {
                for(File file:filePaths){
                    content = new MimeBodyPart();
                    if(file.exists()){//附件存在磁盘中
                        FileDataSource fds = new FileDataSource(file);//得到数据源
                        content.setDataHandler(new DataHandler(fds));//得到附件本身并至入BodyPart
                        log.info("添加邮件附件:" + fds.getName() );
                        content.setFileName(MimeUtility.encodeText(fds.getName()));//得到文件名同样至入BodyPart
                        mainPart.addBodyPart(content);
                    }
                }
            }

            //将MimeMultipart对象设置为邮件内容
            mailMessage.setContent(bodyMultipart);
            mailMessage.saveChanges();
            Transport.send(mailMessage);//发送邮件
            log.info("邮件发送成功！");

            return true;
        }catch (Exception e) {
            log.error("发送邮件异常：" + e.getMessage(), e);
            e.printStackTrace();
        }finally{
            log.info("发送完毕邮件之后删除图片" + pngFileName);
        }

        return false;
    }


    /**
     *
     * desc:邮件发送,以HTML格式发送邮件
     * @author KKl yangpingguan2008@126.com
     * @param mailto
     * @param mailcc
     * @param subject
     * @param mailContent
     * @param fileList
     */
    public static void mailPicHtmlSender(String mailto,String mailcc,String subject, String mailContent, List<File> fileList, String pngFileName){

        log.info("发送邮件通知...");
        Properties properties = PropertyUtil.getProperties("umfWeChatPlat_appConf.properties");
        String smtpserver = properties.getProperty("mail.smtp.host"); //邮箱服务器设置
        String smtpport = properties.getProperty("mail.smtp.port"); //邮件服务器默认端口
        String smtpuser = properties.getProperty("mail.username"); //邮件服务器登陆用户名
        String smtppwd = properties.getProperty("mail.password"); //邮件服务器登陆密码
        String mailfrom = properties.getProperty("mail.from"); //发件人
        String timeout = properties.getProperty("mail.timeout"); //超时时间
        String connectTimeout =properties.getProperty("mail.connect.timeout"); //SOCKET连接的超时设置
        String mailfromname = properties.getProperty("mail.fromname"); //发件人名称
        
//        String smtpserver = PropertiesTool.getValue("mail.smtp.host"); //邮箱服务器设置
//        String smtpport = PropertiesTool.getValue("mail.smtp.port"); //邮件服务器默认端口
//        String smtpuser = PropertiesTool.getValue("mail.username"); //邮件服务器登陆用户名
//        String smtppwd = PropertiesTool.getValue("mail.password"); //邮件服务器登陆密码
//        String mailfrom = PropertiesTool.getValue("mail.from"); //发件人
//        String mailfromname = PropertiesTool.getValue("mail.fromname"); //发件人名称
//
//        String timeout = PropertiesTool.getValue("mail.timeout"); //超时时间
//        String connectTimeout = PropertiesTool.getValue("mail.connect.timeout");//SOCKET连接的超时设置

        MailInfo mailInfo = new MailInfo();
        mailInfo.setMailServerHost(smtpserver);
        mailInfo.setMailServerPort(smtpport);
        mailInfo.setValidate(true);
        mailInfo.setUsername(smtpuser);		//邮件服务器用户名
        mailInfo.setPassword(smtppwd);		// 您的邮箱密码
        mailInfo.setFromAddress(mailfrom);	//
        mailInfo.setFromAddressName(mailfromname);
        mailInfo.setToAddress(mailto);
        mailInfo.setTimeout(timeout);//超时设置
        mailInfo.setConnectTimeout(connectTimeout);
        mailInfo.setSubject(subject);		//邮件主题
        mailInfo.setAttachFileNames(fileList);//附件
        mailInfo.setContent(mailContent);
        SendMailUtil.sendPicHtmlMail(mailInfo,  pngFileName);// 发送html格式
//		SendMailUtil.sendHtmlMail(mailInfo);
    }

    public static void main(String[] args) throws Exception {

        System.setProperty("resin.home", "D:\\softwaresetup\\resin-4.0.48");
        List<String> fileNames = new ArrayList<String>();
        fileNames.add("D:\\文件夹作用说明.txt");

        List<File> fileList = new ArrayList<File>();
        File file = new File("D:\\文件夹作用说明1.txt");
        File file2 = new File("D:\\文件夹作用说明2.txt");
        fileList.add(file);
        fileList.add(file2);

        String mailto = "lihongpeng@umpay.com";//收件人
        String subject = "微信应用平台测试邮件发送模块";//邮件标题
        String mailContent = "测试邮件";//邮件内容

//        SendMailUtil.mailPicHtmlSender(mailto,"lihongpeng@umpay.com", subject, mailContent, fileList,"D:\\a.jpg");

        SendMailUtil.sendMail(mailto, subject,mailContent, fileList);
    }
}
